package life.graph;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;

import javax.swing.Timer;

import life.Coordinate;
import life.Food;
import life.Liso;
import life.World;

class LisoAnimation01 extends Panel implements ActionListener
{

	int millisec; /* ogni quanti millisecondi si muove */
	Timer timer; /* per regolare l'animazione */
	World world;
	int lisoLifeSpan = 150;
	int foodLifeSpan = 5000;
	Color blue = new Color(0, 0, 255, 10);
	Color blueD = new Color(0, 0, 255);
	Color green = new Color(0, 255, 0, 90);
	int cycle = 0;
	private String pathStatFile;
	private StringBuffer sbStat= new StringBuffer();

	public LisoAnimation01(int velocita, double extension, String path, String pathStatFile)
	{
		millisec = velocita;
		world = new World(new Coordinate(extension, extension));
		this.pathStatFile=pathStatFile;
		if (path != null && !path.equalsIgnoreCase(""))
		{
			System.out.println("Load from file " + path);
			LisoReader lr = new LisoReader(path);
			lr.process();
			world.setLisoMap(lr.getLisoMap());
			world.setFoodMap(lr.getFoodMap());
			cycle=lr.getCycle();
			this.pathStatFile=lr.getPathStatFile();
			System.out.println("Liso: "+ world.getLisoMap().size());
			System.out.println("Food: "+ world.getFoodMap().size());
			System.out.println("Cycle: "+cycle);
			System.out.println("StatPath: "+ this.pathStatFile);
		}
		else
		{
			int foodAmmonut = 20;
			int lisoAmmonut = 22;

			world.createFood(foodAmmonut, foodLifeSpan); // set Food
			world.createLiso(lisoAmmonut, lisoLifeSpan); // Set Liso
		}
		
		timer = new Timer(millisec, this);
		timer.start();
	}

	/*
	 * azione da compiere quando scatta il timer, sposta il cerchio e poi invoca
	 * il ridisegno
	 */
	public void actionPerformed(ActionEvent e)
	{
		world.age(); // Age world
		world.foodAwarness();
		world.moveLiso(); // move Liso in the world
		double foodSpawnProbablility = .2;
		world.spawnFood(foodSpawnProbablility, foodLifeSpan); // Spawn New Food
		world.lisoEat(); // Liso eat if can
		world.spawnLiso();
		cycle++;
		System.out.println(cycle + "\tfood:" + world.getFoodMap().size() + "\tLiso:" + world.getLisoMap().size() + "\tborn:" + world.getBorn() + "\tdie:" + world.getDie() + "\tprob:"
				+ world.getProb());
		sbStat.append(cycle);
		sbStat.append(";");
		sbStat.append(world.getFoodMap().size());
		sbStat.append(";");
		sbStat.append(world.getLisoMap().size());
		sbStat.append(";");
		sbStat.append(world.getBorn());
		sbStat.append(";");
		sbStat.append(world.getDie());
		sbStat.append(";");
		sbStat.append(world.getProb());
		sbStat.append(";");
		sbStat.append(world.getLisoStat());
		sbStat.append("\n");

		if (!world.asLisoAlive())
		{
			writeReport();
			timer.stop();
		}

		if (cycle % 100 == 0)
			writeReport();
		// repaint();

	}

	private void writeReport()
	{
		System.out.println("Save Data");
		StringBuffer lisoStat = new StringBuffer();
		if (world.getLisoMap().size() > 0)
		{
			for (Liso l : world.getLisoMap())
			{
				lisoStat.append(l.dumpToString());
				lisoStat.append("\n");
			}
			for(Food f: world.getFoodMap())
			{
				lisoStat.append(f.dumpToString());
				lisoStat.append("\n");
			}

			lisoStat.append("cycle");
			lisoStat.append(";");
			lisoStat.append(cycle);
			lisoStat.append("\n");

			lisoStat.append("pathStatFile");
			lisoStat.append(";");
			lisoStat.append(pathStatFile);
			lisoStat.append("\n");
		}

		try
		{
		    FileWriter fw = new FileWriter(pathStatFile,true); //the true will append the new data
		    fw.write(sbStat.toString());//appends the string to the file
		    fw.close();

		}
		catch (Exception e)
		{
			System.err.println("Error writing "+pathStatFile+": " + e.getMessage());
		}
		
		try
		{
			FileWriter fstream = new FileWriter("c:/tmp/LISO/LisoMap.csv");
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(lisoStat.toString());
			out.close();

		}
		catch (Exception e)
		{
			System.err.println("Error:  writing mapFile" + e.getMessage());
		}
		


		sbStat= new StringBuffer();
		System.out.println("Save Data: Done");
	}

	public void paint(Graphics g)
	{
		super.paint(g);
		for (Liso liso : world.getLisoMap())
		{
			g.setColor(blue);
			g.drawOval(liso.getX() - (int) liso.getRadiusPeception(), liso.gety() - (int) liso.getRadiusPeception(), (int) liso.getRadiusPeception() * 2, (int) liso.getRadiusPeception() * 2);
			g.drawOval(liso.getX() - 1, liso.gety() - 1, 2, 2);
			g.drawLine(liso.getX(), liso.gety(), (int) (liso.getX() + liso.getVel().getX() * liso.getVelocityMod() * 5), (int) (liso.gety() + liso.getVel().getY() * liso.getVelocityMod() * 5));
			// System.out.println(liso);
		}

		g.setColor(green);
		for (Food food : world.getFoodMap())
		{
			g.fillRect(food.getX(), food.gety(), 4, 4);
			// System.out.println(food);
		}
	}

	public static void main(String[] args)
	{
		Frame f = new Frame("Liso graph 0.1");
		LisoAnimation01 pp = new LisoAnimation01(200, 400., "C:/tmp/LISO/LisoMap.csv","");
		//LisoAnimation01 pp = new LisoAnimation01(200, 400., "","c:/tmp/LISO/LisoStat.csv");
		// pp.setBackground(Color.white);
		// f.add(pp);
		// f.setSize(new Dimension(600, 600));
		// f.setVisible(true);
	}

	public int getCycle()
	{
		return cycle;
	}

	public void setCycle(int cycle)
	{
		this.cycle = cycle;
	}
	
}